/**
 * 
 */
package edu.pw.treegrid.server.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

import edu.pw.treegrid.server.filter.Filter;
import edu.pw.treegrid.server.message.Hierarchy;
import edu.pw.treegrid.server.message.Path;
import edu.pw.treegrid.server.message.Request;
import edu.pw.treegrid.server.message.ResponseFetchChilds;
import edu.pw.treegrid.server.model.DomainObject;
import edu.pw.treegrid.server.query.QueryGenerator;
import edu.pw.treegrid.server.query.QueryTree;
import edu.pw.treegrid.server.reportmodel.Report;
import edu.pw.treegrid.server.reportmodel.ReportSimpleColumn;
import edu.pw.treegrid.shared.ReportColumnDescription;

/** 
 * @author Piotrek
 */
public class TreeGridServiceImpl implements TreeGridService {
	private static Logger log = Logger.getLogger("xalan.reports");
	
	private QueryGenerator queryGenerator;

	public void setQueryGenerator(QueryGenerator queryGenerator) {
		this.queryGenerator = queryGenerator;
	}

	private DataSource dataSource;
	
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	private TableRow2DomainObjectConverter converter;

	public void setConverter(TableRow2DomainObjectConverter converter) {
		this.converter = converter;
	}

	public void fetchChilds(Request request, ResponseFetchChilds result) {
		log.info("fetchChilds() poczatek");
		Report report = request.getReport();
		Hierarchy hierarchy = request.getHierarchy();
		Filter filter = request.getFilter();
		Path path = request.getPath();
		QueryTree queryTree = queryGenerator.generateQueryTree(report, hierarchy, filter, path);
		ResultSet rs = null;
		PreparedStatement stm = null;
		try {
			log.info("fetchChilds() przed fetch");
			
			String sql = queryTree.generateQuery().getQuery();
			log.info(sql);
			Connection con = dataSource.getConnection();
			stm = con.prepareStatement(sql);
			Map<Integer, Object> parameters = queryTree.getParameters();
			for(Integer parameterIndex: parameters.keySet()) {
				stm.setObject(parameterIndex, parameters.get(parameterIndex));
			}
			
			log.info("fetchChilds() przed executeQuery()");
			rs = stm.executeQuery();
			log.info("fetchChilds() za executeQuery()");
			List<DomainObject> objects = converter.convertResultSetToDomainObjects(rs, request, queryTree);
			log.info("fetchChilds() za convertResultSetToDomainObjects()");
			result.setDomainObjects(objects);
			rs.close();
			log.info("fetchChilds() za rs.close()");
			stm.close();
			log.info("fetchChilds() za stm.close()");
			con.close();
			log.info("fetchChilds() za con.close()");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			log.error( "fetchChilds () ", e );
		}finally {
			if ( rs != null ){ try { rs.close(); }catch( SQLException e ) { } }
			if ( stm != null ){ try { stm.close(); }catch( SQLException e ) { } }
		}
		log.info("fetchChilds() koniec");
	}

	@Override
	public String getColumnTitle(ReportSimpleColumn rsc) {
		if(rsc.isDynamicTitle()) {
            return fetchTitle(rsc.getTitle());
	    }

		return rsc.getTitle();
	}
	
	private String fetchTitle(String query) {
        String title = "";
        try {
            	//if(this.con == null) {
            	Connection con = this.dataSource.getConnection();
    			//}
                Statement stm = con.createStatement();
                stm.execute(query);
                ResultSet rs = stm.getResultSet();
                rs.next();
                title = rs.getString(1);
                rs.close();
                stm.close();
                con.close();
        } catch (SQLException e) {
                title = e.getErrorCode() + " " + e.getMessage();
                e.printStackTrace();
        }
        return title;
}
}